{% extends 'generic/object_create.html' %}
{% load static %}
{% load form_helpers %}

{% block form_errors %}
    {% if form.non_field_errors %}
        <div class="card border-danger">
            <div class="card-header bg-danger-subtle border-danger text-body"><strong>Errors</strong></div>
            <div class="card-body">
                {{ form.non_field_errors }}
                {% for child in children.forms %}
                    {% if child.errors %}
                        {% for error in child.errors.values %}{{ error }}{% endfor %}
                    {% endif %}
                {% endfor %}
            </div>
        </div>
    {% endif %}
{% endblock %}

{% block form %}
    <div class="card">
        <div class="card-header"><strong>Dynamic Group</strong></div>
        <div class="card-body">
            {% render_field form.name %}
            {% render_field form.description %}
            {% render_field form.content_type %}
            {% render_field form.group_type %}
            {% render_field form.tenant %}
        </div>
    </div>
    <div class="card">
        <div class="card-header"><strong>Filter Options</strong></div>
        <div class="card-body">
            <ul class="nav nav-tabs" role="tablist">
                <li role="presentation" class="nav-item">
                    <a class="nav-link active" href="#filter-form" role="tab" data-bs-toggle="tab">Filter Fields</a>
                </li>
                <li class="nav-item" role="presentation">
                    <a class="nav-link" href="#children-form" role="tab" data-bs-toggle="tab">Child Groups</a>
                </li>
            </ul>
            <div class="tab-content">
                <div class="tab-pane active" id="filter-form">
                    {% if filter_form %}
                        <span class="form-text mb-12">
                            Select the filtering criteria to determine membership of objects matching
                            the Content Type for this Dynamic Group. Fields that are not a dropdown are
                            expected to have string inputs and do not support multiple values.
                        </span>

                        <div class="card">
                            <div class="card-header"><strong>Object Fields</strong></div>
                            <div class="card-body">
                                {% render_form filter_form excluded_fields="[]" %}
                            </div>
                        </div>

                        {% if filter_form.custom_fields %}
                            <div class="card">
                                <div class="card-header"><strong>Custom Fields</strong></div>
                                <div class="card-body">
                                    {% render_custom_fields filter_form %}
                                </div>
                            </div>
                        {% endif %}

                        {% if filter_form.relationships %}
                            <div class="card">
                                <div class="card-header"><strong>Relationships</strong></div>
                                <div class="card-body">
                                    {% render_relationships filter_form %}
                                </div>
                            </div>
                        {% endif %}

                    {% else %}
                        <span class="form-text">
                            Filtering criteria will be available after initially saving this group and
                            returning to this page.
                        </span>
                    {% endif %}
                </div>
                <div class="tab-pane overflow-auto" id="children-form">
                    {% if children.errors %}
                        <div class="text-danger">
                            Please correct the error(s) below:

                            {% for child in children.forms %}
                                {% if child.errors %}
                                    {% for error in child.errors.values %}{{ error }}{% endfor %}
                                {% endif %}
                            {% endfor %}
                        </div>
                    {% endif %}
                    {{ children.non_field_errors }}
                    <table class="table" id="children">
                        {{ children.management_form }}
                        {% for child_form in children.forms %}
                            {% if forloop.first %}
                                <thead>
                                    <tr>
                                        <th>Weight</th>
                                        {% for field in child_form.visible_fields %}
                                            <th>{{ field.label|capfirst }}</th>
                                        {% endfor %}
                                    </tr>
                                </thead>
                            {% endif %}
                            <tr class="formset_row-{{ children.prefix }}">
                                <td><i class="mdi mdi-drag-horizontal drag-handler"></i></td>
                                {% for field in child_form.visible_fields %}
                                    <td>
                                        {% if forloop.first %}
                                            {% for hidden in child_form.hidden_fields %}
                                                {{ hidden }}
                                            {% endfor %}
                                        {% endif %}
                                        {{ field }}
                                        {% if field.errors %}
                                            <ul>
                                                {% for error in field.errors %}
                                                    {# Embed an HTML comment indicating the error for extraction by tests #}
                                                    <!-- FORM-ERROR {{ field.name }}: {{ error }} -->
                                                    <li class="text-danger">{{ error }}</li>
                                                {% endfor %}
                                            </ul>
                                        {% endif %}
                                    </td>
                                {% endfor %}
                            </tr>
                        {% endfor %}
                    </table>
                </div>
            </div>
        </div>
    </div>
    {% include 'inc/extras_features_edit_form_fields.html' %}
{% endblock form %}

{% block javascript %}
    {{ block.super }}
    <script src="{% static 'jquery/jquery.formset.js' %}"></script>
    <script type="text/javascript">
        $('.formset_row-{{ children.prefix }}').formset({
            addText: '<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add another Group',
            addCssClass: 'btn btn-primary add-row',
            deleteText: '<span class="mdi mdi-trash-can-outline" aria-hidden="true"></span>',
            deleteCssClass: 'btn btn-danger delete-row',
            prefix: '{{ children.prefix }}',
            formCssClass: 'dynamic-formset-{{ children.prefix }}',
            added: jsify_form
        });

    // Function that takes a Dynamic Group children form and recomputes the weights.
        function update_weights(children_form){
            let w = 10;
            $(children_form).find('.formset_row-{{ children.prefix }}').each((i, el) => {

            // A child is considered "weight-able" if any of the settable values contains a value
            // If a user is in the middle of setting a group we want to consider it for weight
            // We also want to remove the weight if it's empty to not throw a field value error on a hidden field
            //
            // el = child row
            // sel = a select element either specifying the child group or operator
            //         we don't need to worry about which one we are looking at, just if it has a value
                let contains_value = $(el).find("select[name$='-group'], select[name$='-operator']") // Get any select element in this row ending in -group or -operator
                    .toArray() // Convert to Array to access .some() method
                    .some((x) => { return ($(x).val().length > 0) === true }) // Evaluate if any element in this row has a value length over 0
                // .some(fn(x)) will return a true/false if any item in the array return true when passed into the evaluator function



                let weight_input = $(el).find("*[name$='-weight']")
                weight_input.val("") // Reset the value to start clean always
                if(contains_value) {
                    weight_input.val(w); // Set a weight
                    w += 10; // Following current convention by allowing space between children to aid in API interface.
                         //   If someone wants to add a child later via the API they can insert a child between children without
                         //   having to re-weight all children following first.
                }
            })
        }

    // Make the children form formset rows draggable and hook to re-weight on drag complete.
        $('#children-form').sortable({
            handle: '.drag-handler',
            items: '.formset_row-{{ children.prefix }}',
            update: ( e, ui ) => {
                update_weights(e.target)
            }
        });

    // Instead of re-weight on every input change, just do it before we submit the form.
        $('#nb-create-form').submit((e) => {
            $(e.target).find('#children-form').each((i, cf) => { update_weights(cf) });
        });
    </script>
{% endblock javascript %}
